iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0

Widget狀態管理

Widget 類別的原始碼上有標注 @immutable,這個標注的意思是不可變的;簡單的來說這個類別裡的類別屬性必需宣告成 final,經賦值後就不可改變。

@immutable
abstract class Widget extends DiagnosticableTree {
  /// Initializes [key] for subclasses.
  const Widget({ this.key });
  ...

State

在先前的範例中,我們有使用過 StatelessWidget,這類型的控件通常只需要定義佈局內容,而 StatefulWidget 內部使用 State 來處理狀態變化的管理,可以在收到異動後透過 setState 通知 Flutter 重新渲染畫面。

StatefulWidget

Widget 在設計上是 immutable 的,也就是說控件在經過創建後就不能夠修改,所以 Flutter 設計上將狀態管理的這件事情交由 State 類別來處理。

繼承 StatefulWidget 的控件需要覆寫掉 createState 這個方式,回傳自己定義的 State 對象,在 State 中,我們可以定義想要的屬性,並且定義控件 build 方法,這個方法與 StatelessWidgetbuild 行為一樣是用來定義佈局的內容。

StatefulWidget 的實作可以參考下面時間控件的寫法,在狀態中我們有個字串類別的 _now 屬性用來顯示目前的時間。TimeModel 類別 mixin ChangeNotifier,每隔一秒鐘就會觸發時間變更的事件。

我們在生命週期階段的 initState 監聽時間變更的事件,並在收到事件後更新_now的資料並呼叫setState更新畫面。

class Clock extends StatefulWidget {
  // 這邊的 key 是底層 widget canUpdate 方法有關
  const Clock({Key? key}) : super(key: key);

  @override
  _Clock createState() => _Clock();
}

class _Clock extends State<Clock> {
  // TimeModel 自己實作的時間類別
  // 此類別 mixin ChangeNotifier 類別,提供`觀察者模式`的特性
  final TimeModel time = TimeModel();

  String _now = "";

   // 透過呼叫 setState 通知狀態已異動
  _updateTime() {
    setState(() {
      _now = time.toString();
    });
  }

  // State 生命週期
  @override
  void initState() {
    print('====initState===');
    super.initState();
    // 監聽事件
    time.addListener(_updateTime);
  }

  @override
  Widget build(BuildContext context) {
    print('====build====');
    return Text(_now);
  }
}

今日成果

statefulwidget_time

小結

練習成果

重點回顧:

  1. 從控件狀態管理是否可變更來區分,控件有 StatelessWidgetStatefulWidget 兩種。
  2. 需要狀態的話使用 StatefulWidget,並定義 State 物件。
  3. 資料異動後,需要觸發 setState 通知 widget

上一篇
Flutter體驗 Day 5-Widget 樂高積木
下一篇
Flutter體驗 Day 7-State生命週期
系列文
Flutter / Dart 跨平台App開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言